﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RadowCore.Models;
namespace RadowCore.Helpers
{
    class PolicyBuilder
    {
        public static Policy GeneratePolicy1()
        {
            FlowNode fn1 = new FlowNode("OriginatorB", "OriginatorE");
            FlowNode fn2 = new FlowNode("OriginatorE", "OriginatorG");
            List<OpNode> fnList = new List<OpNode>();
            fnList.Add(fn1);
            fnList.Add(fn2);
            ConjunctNode cn = new ConjunctNode(fnList);
            List<ConjunctNode> cnList = new List<ConjunctNode>();
            cnList.Add(cn);
            DisjunctNode dn = new DisjunctNode(cnList);
            RadowCore.Models.Rule r1 = new RadowCore.Models.Rule();
            r1.Source = "OriginatorB";
            r1.Destination = "OriginatorG";
            r1.Exception = dn;
            Policy p = new Policy("policy");
            p.RuleList.Add(r1);
            RadowCore.Models.Rule r2 = new RadowCore.Models.Rule();
            r2.Source = "OriginatorA";
            r2.Destination = "OriginatorG";
            r2.Exception = new FalseNode();
            p.RuleList.Add(r2);
            return p;
        }
        /// <summary>
        /// generates a policy for the productOrder log
        /// </summary>
        /// <returns>a policy contains the following rules:
        /// <br/>a flow between Customer_Service_Role role and Stock_Role role is prevented unless it passes through Financial_Role role.
        /// </returns>
        public static Policy GenerateProductOrderPolicy()
        {
            FlowNode fn1 = new FlowNode("Customer_Service_Role", "Financial_Role");
            fn1.IsRoleType = true;
            FlowNode fn2 = new FlowNode("Financial_Role", "Stock_Role");
            fn2.IsRoleType = true;
            List<OpNode> fnList = new List<OpNode>();
            fnList.Add(fn1);
            fnList.Add(fn2);
            ConjunctNode cn = new ConjunctNode(fnList);
            List<ConjunctNode> cnList = new List<ConjunctNode>();
            cnList.Add(cn);
            DisjunctNode dn = new DisjunctNode(cnList);
            RadowCore.Models.Rule r1 = new RadowCore.Models.Rule();
            r1.Source = "Customer_Service_Role";
            r1.Destination = "Stock_Role";
            r1.Exception = dn;
            Policy p = new Policy("ProductOrderPolicy");
            p.RuleList.Add(r1);            
            return p;
        }

        /// <summary>
        /// generates a policy for the PaperRevision log
        /// </summary>
        /// <returns>a policy</returns>
        public static Policy GeneratePolicyForPaperRevision()
        {
            //flow between author role to reviewer role is prevented unless the users are different.
            NotEqualOp notEqualNode = new NotEqualOp();
            notEqualNode.IsRoleType = false;
            List<OpNode> fnList = new List<OpNode>();
            fnList.Add(notEqualNode);            
            ConjunctNode cn = new ConjunctNode(fnList);
            List<ConjunctNode> cnList = new List<ConjunctNode>();
            cnList.Add(cn);
            DisjunctNode dn = new DisjunctNode(cnList);
            RadowCore.Models.Rule r1 = new RadowCore.Models.Rule();
            r1.Source = "Author_Role";
            r1.Destination = "Reviewer_Role";
            r1.Exception = dn;

            //flow between author reviewer to reviewer role is prevented unless the users are the same.
            EqualsOp equalNode = new EqualsOp();
            equalNode.IsRoleType = false;
            List<OpNode> fnList2 = new List<OpNode>();
            fnList2.Add(equalNode);
            ConjunctNode cn2 = new ConjunctNode(fnList2);
            List<ConjunctNode> cnList2 = new List<ConjunctNode>();
            cnList2.Add(cn2);
            DisjunctNode dn2 = new DisjunctNode(cnList2);
            RadowCore.Models.Rule r2 = new RadowCore.Models.Rule();
            r2.Source = "Reviewer_Role";
            r2.Destination = "Reviewer_Role";
            r2.Exception = dn2;

            //adding the rules to the policy
            Policy p = new Policy("PaperRevisionPolicy");
            p.RuleList.Add(r1);
            p.RuleList.Add(r2);
            return p;
        }

        /// <summary>
        /// generates a policy for the FlightReservation log
        /// </summary>
        /// <returns>a policy</returns>
        public static Policy GeneratePolicyForFlightReservation()
        {
            //flow between Airline_Agency_Role role to Airline_Agency_Role role is prevented.
            FalseNode falseNode = new FalseNode();            
            RadowCore.Models.Rule r1 = new RadowCore.Models.Rule();
            r1.Source = "Airline_Agency_Role";
            r1.Destination = "Airline_Agency_Role";
            r1.Exception = falseNode;
           
            //adding the rules to the policy
            Policy p = new Policy("FlightReservationPolicy");
            p.RuleList.Add(r1);
            return p;
        }

        /// <summary>
        /// generates a policy for the LoanRequest log
        /// </summary>
        /// <returns>a policy</returns>
        public static Policy GeneratePolicyForLoanRequest()
        {
            //flow between Client_Role role to Loan_Authorization_Role role is prevented unless it passes through Customer_Service_Role role .
            FlowNode fn1 = new FlowNode("Client_Role", "Customer_Service_Recieve_Role");
            FlowNode fn2 = new FlowNode("Customer_Service_Recieve_Role", "Loan_Authorization_Role");
            fn1.IsRoleType = true;
            fn2.IsRoleType = true;
            List<OpNode> fnList = new List<OpNode>();
            fnList.Add(fn1);
            fnList.Add(fn2);
            ConjunctNode cn = new ConjunctNode(fnList);
            List<ConjunctNode> cnList = new List<ConjunctNode>();
            cnList.Add(cn);
            DisjunctNode dn = new DisjunctNode(cnList);
            RadowCore.Models.Rule r = new RadowCore.Models.Rule();
            r.Source = "Client_Role";
            r.Destination = "Loan_Authorization_Role";
            r.Exception = dn;

            //flow between Customer_Service_Role role to Customer_Service_Role role is prevented unless it passes through Loan_Authorization_Role role .
            FlowNode fn3 = new FlowNode("Customer_Service_Recieve_Role", "Loan_Authorization_Role");
            FlowNode fn4 = new FlowNode("Loan_Authorization_Role", "Customer_Service_Role");
            fn3.IsRoleType = true;
            fn4.IsRoleType = true;
            List<OpNode> fnList2 = new List<OpNode>();
            fnList2.Add(fn3);
            fnList2.Add(fn4);
            ConjunctNode cn2 = new ConjunctNode(fnList2);
            List<ConjunctNode> cnList2 = new List<ConjunctNode>();
            cnList2.Add(cn2);
            DisjunctNode dn2 = new DisjunctNode(cnList2);
            RadowCore.Models.Rule r2 = new RadowCore.Models.Rule();
            r2.Source = "Customer_Service_Recieve_Role";
            r2.Destination = "Customer_Service_Role";
            r2.Exception = dn2;

            //adding the rules to the policy
            Policy p = new Policy("LoanRequestPolicy");
            p.RuleList.Add(r);
            p.RuleList.Add(r2);
            return p;
        }
    
        
        
    
    }
}
